package com.supermap.desktop.theme;

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.font.FontRenderContext;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;

import com.supermap.data.TextStyle;
import com.supermap.desktop.mapview.MapViewProperties;
import com.supermap.desktop.ui.controls.ReadTextStyleTemplateXML;
import com.supermap.desktop.ui.controls.TextStyleDialog;
import com.supermap.desktop.ui.controls.UIEnvironment;

/**
 * 文本模板下拉列表
 */
class TextTemplateComboBox extends JComboBox {
	private static final long serialVersionUID = 1L;

	private transient ActionListener customActionListener = new ActionListener() {

		@Override
		public void actionPerformed(ActionEvent e) {
			if (getSelectedIndex() == getItemCount() - 1) {
				final TextStyleDialog dialog = new TextStyleDialog();
				dialog.setTextStyle(new TextStyle());
				dialog.setVisible(true);
				dialog.dispose();
			}
		}

	};

	private transient TextTemplateComboBoxCellInfo customTextTemplateCellInfo;

	public TextTemplateComboBox() {
		super();
		this.setRenderer(new TextTemplateComboBoxCellRenderer());
		customTextTemplateCellInfo = new TextTemplateComboBoxCellInfo(new TextStyle(), "自定义");
		// 根据base库的位置找xml文件，该方案与云唯英做过沟通
		String str = UIEnvironment.jni_GetBasePath();
		str = str + "Resource/Templates/TextStyle/CommonStyle/";
		File file = new File(str);
		String[] fileNames = file.list();
		for (int i = 0; i < fileNames.length; i++) {
			String xmlFileName = str + fileNames[i];
			TextStyle xmlResult = ReadTextStyleTemplateXML.getTextStyleFromXmlFile(new File(xmlFileName));
			TextTemplateComboBoxCellInfo comboBoxCellInfo = new TextTemplateComboBoxCellInfo(xmlResult, fileNames[i].substring(0, fileNames[i].indexOf(".xml")));

			this.addItem(comboBoxCellInfo);
		}

		this.addItem(customTextTemplateCellInfo);
		this.addActionListener(customActionListener);
	}

	class TextTemplateComboBoxCellRenderer extends JLabel implements ListCellRenderer {
		private static final long serialVersionUID = 1L;

		public TextTemplateComboBoxCellRenderer() {
			setOpaque(true);
			setHorizontalAlignment(JLabel.LEFT);
			setVerticalAlignment(CENTER);
		}

		@Override
		public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
			TextTemplateComboBoxCellInfo cellInfo = (TextTemplateComboBoxCellInfo) value;
			this.setIcon(cellInfo.getImageIcon());
			this.setText(cellInfo.getCaption());
			if (isSelected) {
				this.setBackground(Color.lightGray);
				this.setToolTipText(cellInfo.toString());
			} else {
				this.setBackground(Color.white);
			}
			return this;
		}
	}
}

/**
 * 文本模板单元格信息类
 */
class TextTemplateComboBoxCellInfo {

	// 预览字符串
	private String sampleText = "AaBb";

	// 描述，通常情况下应该就是xml文件的文件名
	private String caption;

	// 字体名
	private String fontName;

	// 图片
	private ImageIcon imageIcon;

	// 粗体
	private boolean bold;

	// 斜体
	private boolean italic;

	// 固定大小
	private boolean fixedSize;

	// 字高
	private double height;

	// 文本风格
	private TextStyle textStyle;

	TextTemplateComboBoxCellInfo(TextStyle textStyle, String caption) {
		this.caption = caption;
		this.textStyle = textStyle.clone();
		fontName = textStyle.getFontName();
		bold = textStyle.getBold();
		italic = textStyle.getItalic();
		fixedSize = textStyle.isSizeFixed();
		height = textStyle.getFontHeight();
		imageIcon = this.getImageIcon();
	}

	TextTemplateComboBoxCellInfo(String caption, String fontName, ImageIcon icon, boolean bold, boolean italic, boolean fixedSize, double height) {
		this.caption = caption;
		this.fontName = fontName;
		imageIcon = icon;
		this.bold = bold;
		this.italic = italic;
		this.fixedSize = fixedSize;
		this.height = height;
	}

	public String getSampleText() {
		return sampleText;
	}

	public void setSampleText(String value) {
		sampleText = value;
	}

	public String getFontName() {
		return fontName;
	}

	public void setFontName(String name) {
		fontName = name;
	}

	public ImageIcon getImageIcon() {
		if (imageIcon == null) {
			int style = 0;
			if (textStyle.getBold()) {
				style |= Font.BOLD;
			}
			if (textStyle.getItalic()) {
				style |= Font.ITALIC;
			}
			Font font = new Font(textStyle.getFontName(), style, 16);

			BufferedImage bufferedImage = new BufferedImage(50, 32, BufferedImage.TYPE_INT_ARGB);
			Graphics graphics = bufferedImage.getGraphics();
			Graphics2D g2 = (Graphics2D) graphics;
			g2.setFont(font);
			// 该方法可以获取文本显示时的下基线，调节该下基线可以达到画下划线和删除线的目的
			FontRenderContext context = g2.getFontRenderContext();
			Rectangle2D bounds = font.getStringBounds(sampleText, context);

			double x = (50 - bounds.getWidth()) / 2;
			double y = (32 - bounds.getHeight()) / 2;
			double ascent = -bounds.getY();
			double baseY = y + ascent;

			graphics.setColor(textStyle.getForeColor());
			g2.drawString(sampleText, (int) x, (int) baseY);

			if (textStyle.getUnderline()) {
				g2.draw(new Line2D.Double(x, baseY, x + bounds.getWidth(), baseY));
			}
			if (textStyle.getStrikeout()) {
				g2.draw(new Line2D.Double(x, baseY - bounds.getHeight() / 3, x + bounds.getWidth(), baseY - bounds.getHeight() / 3));
			}

			imageIcon = new ImageIcon(bufferedImage);
		}
		return imageIcon;
	}

	public void setImageIcon(ImageIcon icon) {
		imageIcon = icon;
	}

	public boolean getBold() {
		return bold;
	}

	public void setBold(boolean bold) {
		this.bold = bold;
	}

	public boolean getItalic() {
		return italic;
	}

	public void setItalic(boolean italic) {
		this.italic = italic;
	}

	public boolean getFixedSize() {
		return fixedSize;
	}

	public void setFixedSize(boolean fixedSize) {
		this.fixedSize = fixedSize;
	}

	public double getHeight() {
		return height;
	}

	public void setHeight(double height) {
		this.height = height;
	}

	public String getCaption() {
		return caption;
	}

	public void setCaption(String caption) {
		this.caption = caption;
	}

	public TextStyle getTextStyle() {
		return textStyle;
	}

	@Override
	public String toString() {
		StringBuilder buffer = new StringBuilder();
		buffer.append(fontName);
		buffer.append(File.separator);

		if (bold) {
			buffer.append(MapViewProperties.getString("String_Bold"));
			buffer.append(File.separator);
		}
		if (italic) {
			buffer.append(MapViewProperties.getString("String_Italic"));
			buffer.append(File.separator);
		}
		if (fixedSize) {
			buffer.append(MapViewProperties.getString("String_FixedSize"));
			buffer.append(File.separator);
		}
		buffer.append(MapViewProperties.getString("String_Height") + height);

		return buffer.toString();
	}
}
